package edu.uic.readfile;

import java.io.*;
import java.util.*;

public class KNNgao
{

	static int length = 1;
	static int Article_No = 0;
	static int k = 6;
	static double score = 0;
	// String fname ="";
	private Vector<Double> center;
	private Vector<Vector<Double>> neighbor = new Vector(); // neigbors article
	private LinkedHashMap<String, Vector<Double>> neighbors = new LinkedHashMap();
	private TreeMap<Double, String> distMap = new TreeMap<Double, String>();
	private double dist[][];
	private TrainingData td;
	
	public void setCenter(SingleFile file)
	{
		center = new Vector<Double>(file.normalVector);
		length = center.size();
	}
	
	public void addneighbor(SingleFile file)
	{
		neighbor.add(new Vector<Double>(file.normalVector));
		neighbors.put(file.fileID, new Vector<Double>(file.normalVector));
		Article_No++;
	}
	
	public void addneighbors(TrainingFileSet fileSet)
	{
		for(SingleFile file : fileSet.trainingSet)
		{
			addneighbor(file);
			Article_No++;
		}
	}
	
	public void print_neighbor()
	{
		for (int i = 0; i < neighbor.size(); i++)
		{
			for (int j = 0; j < neighbor.get(i).size(); j++)
			{
				System.out.printf("%f,", neighbor.get(i).get(j).doubleValue());
			}

			System.out.println();
		}

	}

	public void print_center()
	{
		for (int i = 0; i < center.size(); i++)
			System.out.printf("%f,", center.get(i).doubleValue());
		System.out.println();

	}

	public void print_dist()
	{
		for (int i = 0; i < Article_No; i++)
		{
			System.out.printf("%f, %f\n", dist[i][0], dist[i][1]);
		}
	}
	
	public KNNgao(TrainingData td)
	{
		super();
		this.td = td;
		addneighbors(td.fileset);
		setCenter(td.fileset.trainingSet.get(0));
	}

	public KNNgao(int len_n, int k_n, int a_n, String fname) throws IOException
	{
		length = len_n; // 767
		k = k_n;// 3
		//Article_No = a_n;// 10,9
		// this.fname = f;
		
		/*
		 * for(int i =0; i< a_n;i++) { Vector<Double> ac = new Vector<Double>();
		 * neighbor.add(ac); }
		 */
		boolean c = true;
		Scanner in = new Scanner(new FileInputStream(fname));
		while (in.hasNextLine())
		{
			String line = in.nextLine();
			StringTokenizer lineTokenizer = new StringTokenizer(line, " ");
			Vector<Double> l = new Vector<Double>();

			while (lineTokenizer.hasMoreTokens())
			{
				String num = lineTokenizer.nextToken();
				Double temp = Double.parseDouble(num);
				l.add(temp);
			}
			if (c == true)
			{
				center = l;
				c = false;
			} else
				this.neighbor.add(l);

		}
		
		length = center.size();
		Article_No = neighbor.size();
		System.out.println(length + " " + Article_No);
		dist = new double[Article_No][2];
		center = new Vector<Double>();
		neighbor = new Vector<Vector<Double>>(Article_No);

	}

	public double distance(Vector<Double> a, Vector<Double> b)
	{
		double d = 0;
		double ab = 0;
		double a2 = 0;
		double b2 = 0;

		if (a.size() != b.size())
		{
			System.out.println("not the same size");
			System.out.println(b.size());
			System.out.println(neighbor.size());
			System.exit(1);
		}

		int size = a.size();
		for (int i = 0; i < size; i++)
		{

			ab += a.get(i).doubleValue() * b.get(i).doubleValue();
			a2 += Math.pow((Double) a.get(i).doubleValue(), 2);
			b2 += Math.pow((Double) b.get(i).doubleValue(), 2);
		}

		d = ab / (Math.sqrt(a2) * Math.sqrt(b2));
		return d;
	}

	public void findKNN()
	{
		for (int i = 0; i < Article_No; i++)
		{
			dist[i][0] = distance(center, (Vector<Double>) neighbor
					.elementAt(i));
			dist[i][1] = i;
		}

		// sort dist in ascending order
		for (int i = 1; i < Article_No; i++)
		{
			if (dist[i][0] < dist[i - 1][0])
			{
				int j = i - 1;
				double temp = dist[i][0];
				double tmpi = dist[i][1];

				do
				{
					dist[j + 1][0] = dist[j][0];
					dist[j + 1][1] = dist[j][1];
				} while (--j >= 0 && temp < dist[j][0]);
				dist[j + 1][0] = temp;
				dist[j + 1][1] = tmpi;
			}
		}
	}
	
	public void getKNN()
	{
		for(String strid : neighbors.keySet())
		{
			Double dist = distance(center, neighbors.get(strid));
			distMap.put(dist, strid);
		}
		
		
		double base = distMap.firstKey();
		
		
		Iterator itr = distMap.keySet().iterator();
		for(int i = 0; i < k; i++)
		{
			score  = score + base/(Double)itr.next()*td.fileset.fileMap.get(distMap.get((Double)itr.next())).value;
		}
		
	}
	
	
	public void printResult()
	{
		for(Double dist : distMap.keySet())
		{
			System.out.println(dist + " " + distMap.get(dist) + " " + td.fileset.fileMap.get(distMap.get(dist)).fileName);
		}
	}
	

	public static void main(String args[]) throws IOException
	{

		
		KNNgao knntest = new KNNgao(4737, 5, 85, "economyvector.txt");
		knntest.findKNN();
		knntest.print_dist();
		//knntest.print_center();
		// knntest.print_neighbor();
		
		//WordSetConstructor rf = new WordSetConstructor();
		//System.out.println("begin");		
		//rf.readFile("liberal_abortion");
		//TrainingData td = new TrainingData();
		//td.wordset.readfromFile();
		//td.transferFile("liberal_abortion");
		
		//KNN knn = new KNN(td);
		//knn.getKNN();
		//knn.printResult();

	}

}
